package com.ocean.product.domain;


import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: NcFileParse
 * @Description: Nc文件解析
 * @Author: liu
 * @Date: 2024-08-08
 * @Version: 1.0
 **/
@Slf4j
public class NcFileParse {

    private static final String[] LON_LAT_STR = new String[]{"lon", "lat", "longitude", "latitude"};
    //缩放因子
    private static final String SCALE_FACTOR = "scale_factor";
    private static final String LON = "lon";
    private static final String LAT = "lat";

    public static void main(String[] args) {
     /*   String filename = "E:\\11.nc";
        List<HeatMap> ParseNcFile = ParseNcFile(filename, "温度");
        //结果写入json文件
        String jsonPrettyStr = JSONUtil.toJsonPrettyStr(ParseNcFile);
        //写到temp.json文件中
        FileUtil.writeUtf8String(jsonPrettyStr, "temp.json");
        log.info("解析完成");*/

    }

    /**
     * 解析nc文件
     * @param filePath
     * @return
     */
  /*  public static List<HeatMap> ParseNcFile(String filePath) {
        List<HeatMap> heatMapList = new ArrayList<>();
        try (NetcdfFile open = NetcdfFile.open(filePath))  {
            //读取nc中的第一个平面数据
            Variable data = open.findVariable("data");
            ImmutableList<Dimension> dimensions = (ImmutableList<Dimension>) Objects.requireNonNull(data).getDimensions();
            // 获取变量的平面数据形状
            int[] shape = new int[dimensions.size()];
            for (int i = 0; i < dimensions.size(); i++) {
                Dimension dimension = dimensions.get(i);
                String name = dimension.getName();
                if (Arrays.asList(LON_LAT_STR).contains(name)) {
                    shape[i] = dimension.getLength();
                } else {
                    shape[i] = 1;
                }
            }
            double[] dataD;
            // 根据平面形状读取数据
            if (DataType.FLOAT.equals(data.getDataType()) || DataType.DOUBLE.equals(data.getDataType())) {
                dataD = (double[]) data.read(new int[dimensions.size()], shape).get1DJavaArray(DataType.DOUBLE.getClassType());
            } else {
                int[] dataArr = (int[]) data.read(new int[dimensions.size()], shape).get1DJavaArray(DataType.INT.getClassType());
                float v = 1f;
                Attribute scaleFactor = data.findAttribute(SCALE_FACTOR);
                if (scaleFactor != null) {
                    v = Objects.requireNonNull(scaleFactor.getNumericValue()).floatValue();
                }
                dataD = new double[dataArr.length];
                for (int i = 0; i < dataArr.length; i++) {
                    dataD[i] = dataArr[i] * v;
                }
            }
            // 获取经纬度信息
            Variable lon = open.findVariable(LON);
            Variable lat = open.findVariable(LAT);
            assert lon != null;
            double[] lonArr = (double[]) lon.read().copyTo1DJavaArray();
            // 计算经度的每个数据点的间隔
            double[] lonIntervals = calculateIntervals(lonArr);
            double longitudeInterval = lonIntervals[1];
            assert lat != null;
            double[] latArr = (double[]) lat.read().copyTo1DJavaArray();
            double[] latIntervals = calculateIntervals(latArr);
            double latitudeInterval = latIntervals[1];
            // 计算经度的最小和最大值
            double minLon = lonArr[0];
            double maxLon = lonArr[lonArr.length - 1];
            // 计算纬度的最小和最大值
            double minLat = latArr[0];
            double maxLat = latArr[latArr.length - 1];
            // 遍历所有经纬度点{}
            for (double lonValue : lonArr) {
                for (double latValue : latArr) {
                    // 这里使用线性搜索替代binarySearch，因为binarySearch需要精确匹配
                    int lonIndex = findIndexOf(lonArr, lonValue);
                    int latIndex = findIndexOf(latArr, latValue);

                    if (lonIndex != -1 && latIndex != -1) {
                        int dataIndex = lonIndex + latIndex * lonArr.length;
                        double targetValue = dataD[dataIndex];
                        //log.info(" 经度={}, 纬度={} , 目标值为:{}", String.format("%.2f", lonValue), String.format("%.2f", latValue), String.format("%.2f", targetValue));
                        HeatMap heatMap = new HeatMap(lonValue, latValue, targetValue);
                        heatMapList.add(heatMap);
                    } else {
                        log.warn("无效的lon或lat值");
                    }
                }
            }
            log.info("经度的最小值：{}", String.format("%.2f", minLon));
            log.info("经度的最大值：{}", String.format("%.2f", maxLon));
            log.info("纬度的最小值：{}", String.format("%.2f", minLat));
            log.info("纬度的最大值：{}", String.format("%.2f", maxLat));
            log.info("经度的间隔：{}", Double.parseDouble(String.format("%.10f", longitudeInterval)));
            log.info("纬度的间隔：{}", Double.parseDouble(String.format("%.10f", latitudeInterval)));
        } catch (InvalidRangeException | IOException e) {
            throw new RuntimeException(e);
        }
        return heatMapList;
    }
*/

    /*public static List<HeatMap> ParseNcFile(String localFilePath, String type) {
        List<HeatMap> ParseNcFile = ParseNcFile(localFilePath);
        ParseNcFile.forEach(heatMap -> {
            heatMap.setDataType(type);
        });
        return ParseNcFile;
    }

    // 线性搜索以便处理不精确匹配的情况
    private static int findIndexOf(double[] arr, double value) {
        int index = Arrays.binarySearch(arr, value);
        // 处理binarySearch返回的负值，表示未找到，转换为插入点索引
        return (index >= 0) ? index : -index - 1;
    }
*/
    /**
     * 计算间隔
     *
     * @param values
     * @return
     */
    private static double[] calculateIntervals(double[] values) {
        double[] intervals = new double[values.length - 1];

        for (int i = 0; i < intervals.length; i++) {
            intervals[i] = values[i + 1] - values[i];
        }
        return intervals;
    }
}